home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / tpio24.zip / DATE24.PAS < prev    next >
Pascal/Delphi Source File  |  1993-01-04  |  21KB  |  702 lines

  1. { DATE24.PAS -- Routines to write, read and compare dates, etc.,
  2.   by Bill Meacham.  Turbo Pascal ver. 3.0.
  3.   You must include IO23.INC before this file.
  4.   Ver 2.0 --  Includes type declarations in this module and allows
  5.               entry of a null date (00/00/0000) -- 1/19/86.
  6.               Cosmetic improvement -- 4/16/86.
  7.   Ver 2.1 --  Function Zeller to determine the day of the week -- 10/8/86.
  8.   Ver 2.1a -  New Read_date -- 10/11/86
  9.   Ver 2.2 --  Made compatible with IO22.INC
  10.   Ver 2.3 --  Changed beep to error_buzz -- 11/25/87
  11.               Added proc Getdate to get DOS date,
  12.               Fixed bug in Read_date -- 11/27/87
  13.               Converted to Unit -- 12/2/87
  14.   Ver 2.4 --  Same as 2.3, except Uses IO24 -- 4/18/88 }
  15.  
  16. { -------------------------------------------------------------------------- }
  17.  
  18. unit date24 ;
  19. {$v-}
  20. interface
  21.  
  22. uses
  23.     crt, dos, io24 ;
  24.  
  25. const
  26.     fdslen     = 29 ;  { length of fulldatestring }
  27.  
  28. type
  29.     date = record
  30.         yr : integer ; { 0 .. 9999 }
  31.         mo : integer ; { 1 .. 12 }
  32.         dy : integer ; { 1 .. 31 }
  33.       end ;
  34.  
  35.     datestring = string[10] ;  { 'MM/DD/YYYY' }
  36.  
  37.     fulldatestring = string[fdslen] ;
  38.  
  39.     juldate = record
  40.         yr  : integer ; { 0 .. 9999 }
  41.         day : integer ; { 1 .. 366 }
  42.       end ;
  43.  
  44.     juldatestring = string[8] ; { 'YYYY/DDD' }
  45.  
  46. const
  47.     null_date     : date       = (yr:0 ; mo:0 ; dy:0) ;
  48.     null_date_str : datestring = 'MM/DD/YYYY' ;
  49.  
  50. function mk_dt_st (dt : date) : datestring ;
  51.   { Makes a string out of a date -- used for printing dates }
  52. procedure write_date (dt: date ; col, row: integer) ;
  53.   { Writes date at column and row specified }
  54. function mk_jul_dt_st (jdt : juldate) : juldatestring ;
  55.   { makes a string out of a julian date }
  56. function leapyear (yr : integer) : boolean ;
  57.   { Whether the year is a leap year or not.
  58.     The year is year and century, e.g. year 1984 is '1984,' not '84' }
  59. function valid_date (dt:date) : boolean ;
  60.   { Test whether date is valid }
  61. procedure read_date (var dt: date ; col, row: integer) ;
  62.   { Read date at column and row specified.  If the user enters only
  63.     two digits for the year, the procedure plugs the century as 1900 or
  64.     2000, but the user can enter all four digits to override the plug. }
  65. function greater_date (dt1, dt2 : date) : integer ;
  66.   { Compares two dates, returns 0 if both equal, 1 if first is
  67.     greater, 2 if second is greater. }
  68. procedure greg_to_jul (dt : date ; var jdt : juldate) ;
  69.   { converts a gregorian date to a julian date }
  70. procedure jul_to_greg (jdt : juldate ; var dt : date) ;
  71.   { converts a julian date to a gregorian date }
  72. procedure next_day (var dt : date) ;
  73.   { Adds one day to the date }
  74. procedure prev_day (var dt : date) ;
  75.   { Subtracts one day from the date }
  76. function date_diff (dt1, dt2 : date) : real ;
  77.   { computes the number of days between two dates }
  78. function month_diff (dt1, dt2 : date ) : integer ;
  79.   { Computes number of months between two dates, rounded. }
  80. function equal_date (dt1, dt2 : date) : boolean ;
  81.   { Tests whether two dates are equal }
  82. function build_full_date_str (dt : date) : fulldatestring ;
  83.   { Build printable string of current date. }
  84. procedure getdate (var dt : date) ;
  85.   { get DOS system date }
  86. function date_and_time : str14 ;
  87.   { get DOS system date and time, return string }
  88.  
  89. { ========================================================================== }
  90.  
  91. implementation
  92.  
  93. type
  94.    montharray = array [1 .. 13] of integer ;
  95.  
  96. const
  97.    monthtotal : montharray = (0,31,59,90,120,151,181,212,243,273,304,334,365) ;
  98.      { used to convert julian date to gregorian and back }
  99.  
  100. { ------------------------------------------------------------ }
  101.  
  102. function mk_dt_st (dt : date) : datestring ;
  103.   { Makes a string out of a date -- used for printing dates }
  104.     var
  105.         yr_st : string[4] ;
  106.         mo_st : string[2] ;
  107.         dy_st : string[2] ;
  108.         dt_st : datestring ;
  109.     begin
  110.         with dt do
  111.           begin
  112.             if (yr=0) and (mo=0) and (dy=0) then
  113.                 dt_st := 'MM/DD/YYYY'
  114.             else
  115.               begin
  116.                 str (yr:4,yr_st) ;
  117.                 str (mo:2,mo_st) ;
  118.                 str (dy:2,dy_st) ;
  119.                 dt_st := concat (mo_st,'/',dy_st,'/',yr_st)
  120.               end  { else }
  121.           end ;  { with dt do }
  122.         mk_dt_st := dt_st
  123.     end ;  { --- proc mk_dt_st --- }
  124.  
  125. { ------------------------------------------------------------ }
  126.  
  127. procedure write_date (dt: date ; col, row: integer) ;
  128.   { Writes date at column and row specified }
  129.     var
  130.         ds : datestring ;
  131.     begin
  132.         ds := mk_dt_st (dt) ;
  133.         write_str (ds,col,row)
  134.     end ; { --- proc write_date --- }
  135.  
  136. { ------------------------------------------------------------ }
  137.  
  138. function mk_jul_dt_st (jdt : juldate) : juldatestring ;
  139. { makes a string out of a julian date }
  140.   var
  141.       yr_st  : string[4] ;
  142.       day_st : string[3] ;
  143.       jdt_st : juldatestring ;
  144.   begin
  145.       with jdt do
  146.         if (yr=0) and (day = 0) then
  147.             jdt_st := 'YYYY/DDD'
  148.         else
  149.           begin
  150.             str(yr:4,yr_st) ;
  151.             str(day:3,day_st) ;
  152.             jdt_st := concat (yr_st,'/',day_st)
  153.           end ;
  154.       mk_jul_dt_st := jdt_st
  155.   end ;  { function mk_jul_dt_st }
  156.  
  157. { ------------------------------------------------------------ }
  158.  
  159. function leapyear (yr : integer) : boolean ;
  160.   { Whether the year is a leap year or not.
  161.     The year is year and century, e.g. year 1984 is '1984,' not '84' }
  162.   begin
  163.     leapyear := ((yr mod 4 = 0) and (not(yr mod 100 = 0)))
  164.              or ( yr mod 400 = 0 )
  165.   end ;
  166.  
  167. { ------------------------------------------------------------ }
  168.  
  169. function valid_date (dt:date) : boolean ;
  170.   { Test whether date is valid }
  171.     var
  172.         bad_fld : integer ;
  173.     begin
  174.         bad_fld := 0 ;
  175.         with dt do
  176.             begin
  177.                 if (mo = 0) and (dy = 0) and (yr = 0) then
  178.                     bad_fld := 0
  179.                 else if not (mo in [1 .. 12]) then
  180.                         bad_fld := 1
  181.                 else if (dy > 31)
  182.                 or (dy < 1)
  183.                 or ((mo in [4,6,9,11]) and (dy > 30)) then
  184.                         bad_fld := 2
  185.                 else if mo = 2 then
  186.                   begin
  187.                     if (leapyear(yr) and (dy > 29))
  188.                     or ((not leapyear(yr)) and (dy > 28)) then
  189.                         bad_fld := 2
  190.                   end
  191.                 else if yr = 0 then
  192.                         bad_fld := 3
  193.             end ; { with dt do }
  194.         valid_date := (bad_fld = 0)
  195.     end ; { function valid_date }
  196.  
  197. { ------------------------------------------------------------ }
  198.  
  199. procedure read_date (var dt: date ; col, row: integer) ;
  200.  
  201. { Read date at column and row specified.  If the user enters only
  202.   two digits for the year, the procedure plugs the century as 1900 or
  203.   2000, but the user can enter all four digits to override the plug. }
  204.  
  205.   var
  206.     ch       : char ;
  207.     savex,
  208.     savey,
  209.     savefld,
  210.     bad_fld,
  211.     key,
  212.     p        : integer ;
  213.     s,
  214.     template : datestring ;
  215.  
  216. { ==================== }
  217.  
  218.   procedure add_to_str ;
  219.     var
  220.       l : integer ;
  221.     begin
  222.       l := length(s) ;
  223.       if l = 10 then
  224.           error_buzz
  225.       else if (l=1) or (l=4) then
  226.         begin
  227.           s := concat(s,ch,'/') ;
  228.           write (ch,'/')
  229.         end
  230.       else
  231.         begin
  232.           s := concat(s,ch) ;
  233.           write (ch)
  234.         end
  235.     end ; { proc add_to_str }
  236.  
  237. { ==================== }
  238.  
  239.   procedure adjust_dt_str ;
  240.     var
  241.       l : integer ;
  242.     begin
  243.       case key of
  244.         del_fld :
  245.           begin
  246.             s := '' ;
  247.             write_str (template,col,row) ;
  248.             gotoxy (col,row)
  249.           end ;
  250.         del_left,
  251.         prev_char :                    { prev_char is destructive backspace! }
  252.           begin
  253.             l := length(s) ;
  254.             if l = 0 then
  255.                 error_buzz
  256.             else if (l=3) or (l=6) then
  257.               begin
  258.                 write (^H,^H,chr(filler),^H) ;
  259.                 delete (s,l-1,2)
  260.               end
  261.             else
  262.               begin
  263.                 write (^H,chr(filler),^H) ;
  264.                 delete (s,l,1)
  265.               end
  266.           end
  267.       end { case }
  268.     end ; { proc adjust_dt_str }
  269.  
  270. { ==================== }
  271.  
  272.   procedure convert_date ;
  273.   { convert the string to a date -- three integers }
  274.     var
  275.       code : integer ;
  276.     begin
  277.       p := pos(' ',s) ;
  278.       while p <> 0 do
  279.         begin
  280.           s[p] := '0' ;
  281.           p := pos(' ',s)
  282.         end ;
  283.       with dt do
  284.         begin
  285.           if (copy(s,1,2) = '') then
  286.             begin
  287.               mo := 0 ; code := 0
  288.             end
  289.           else
  290.               val (copy(s,1,2),mo,code) ;
  291.           if code <> 0 then
  292.             begin
  293.               write ('** CONVERSION ERROR ',code) ;
  294.               halt
  295.             end ;
  296.           if (copy(s,4,2) = '') then
  297.             begin
  298.               dy := 0 ; code := 0
  299.             end
  300.           else
  301.               val (copy(s,4,2),dy,code) ;
  302.           if code <> 0 then
  303.             begin
  304.               write ('** CONVERSION ERROR ',code) ;
  305.               halt
  306.             end ;
  307.           if (copy(s,7,4) = '') then
  308.             begin
  309.               yr := 0 ; code := 0
  310.             end
  311.           else
  312.               val (copy(s,7,4),yr,code) ;
  313.           if code <> 0 then
  314.             begin
  315.               write ('** CONVERSION ERROR ',code) ;
  316.               halt
  317.             end ;
  318.           if not ((yr = 0) and (mo = 0) and (dy = 0)) then
  319.             begin                                          { plug century }
  320.               if yr < 80 then
  321.                   yr := 2000 + yr
  322.               else if yr < 100 then
  323.                   yr := 1900 + yr
  324.             end
  325.         end { with }
  326.     end ; { proc convert_date}
  327.  
  328. { ==================== }
  329.  
  330.   procedure edit_date ;                  { Edit for valid date }
  331.     begin
  332.       bad_fld := 0 ;
  333.       with dt do
  334.         begin
  335.           if (mo = 0) and (dy = 0) and (yr = 0) then
  336.               bad_fld := 0
  337.           else if not (mo in [1 .. 12]) then
  338.               bad_fld := 1
  339.           else if (dy > 31)
  340.           or (dy < 1)
  341.           or ((mo in [4,6,9,11]) and (dy > 30)) then
  342.               bad_fld := 2
  343.           else if mo = 2 then
  344.             begin
  345.               if (leapyear(yr) and (dy > 29))
  346.               or ((not leapyear(yr)) and (dy > 28)) then
  347.                   bad_fld := 2
  348.             end
  349.           else if yr = 0 then
  350.               bad_fld := 3
  351.         end   { with dt do }
  352.     end ; { proc edit_date }
  353.  
  354. { ==================== }
  355.  
  356.   procedure display_date ;               { write date on screen }
  357.     begin
  358.     if (dt.mo = 0) and (dt.dy = 0) and (dt.yr = 0) then
  359.       begin
  360.         write_str (template,col,row) ;
  361.         s := '' ;
  362.         gotoxy (col,row)
  363.       end
  364.     else
  365.       begin
  366.         s := mk_dt_st(dt) ;
  367.         p := pos(' ',s) ;
  368.         while p <> 0 do
  369.           begin
  370.            s[p] := '0' ;
  371.             p := pos(' ',s)
  372.           end ;
  373.         write_str (s,col,row)
  374.       end
  375.     end ;  { proc display_date }
  376.  
  377. { ==================== }
  378.  
  379. begin { proc read_date }
  380.   savefld := fld ;
  381.   ch := chr(filler) ;
  382.   template := concat(ch,ch,'/',ch,ch,'/',ch,ch,ch,ch) ;
  383.   display_date ;
  384.   repeat
  385.       keyin(ch) ;
  386.       key := ord(ch) ;
  387.       if ch in ['0'..'9'] then
  388.           add_to_str
  389.       else if key in adjusting then
  390.           adjust_dt_str
  391.       else if key in terminating then
  392.         begin
  393.           convert_date ;
  394.           edit_date ;
  395.           do_fld_ctl (key) ;
  396.           if bad_fld <> 0 then                  { error message only if }
  397.             begin                               { going forward }
  398.               if (fld < maxint) and (fld > savefld) then
  399.                 begin
  400.                   savex := wherex ;
  401.                   savey := wherey ;
  402.                   case bad_fld of
  403.                     1 : show_msg ('INVALID MONTH') ;
  404.                     2 : show_msg ('INVALID DAY') ;
  405.                     3 : show_msg ('INVALID YEAR')
  406.                   end ; { case }
  407.                   fld := savefld ;              { if bad date, may not go foward }
  408.                   gotoxy (savex,savey)          { restore cursor position }
  409.                 end
  410.             end
  411.         end
  412.       else                                      { invalid character }
  413.           error_buzz
  414.   until not (fld = savefld) ;
  415.   if (bad_fld <> 0) then                        { if bad date, zero it out }
  416.       dt := null_date ;
  417.   write_date (dt,col,row)
  418. end ; { proc read_date }
  419.  
  420. { ------------------------------------------------------------ }
  421.  
  422. function greater_date (dt1, dt2 : date) : integer ;
  423.   { Compares two dates, returns 0 if both equal, 1 if first is
  424.     greater, 2 if second is greater.  Converts both to strings,
  425.     then compares the strings. }
  426.  
  427.     var
  428.         stdt1, stdt2 : string[8] ;
  429.         styr1, styr2 : string[4] ;
  430.         stmo1, stmo2 : string[2] ;
  431.         stdy1, stdy2 : string[2] ;
  432.  
  433.     begin
  434.         with dt1 do
  435.             begin
  436.                 str(yr:4,styr1) ;
  437.                 str(mo:2,stmo1) ;
  438.                 str(dy:2,stdy1) ;
  439.                 stdt1 := concat (styr1,stmo1,stdy1)
  440.             end ;
  441.         with dt2 do
  442.             begin
  443.                 str(yr:4,styr2) ;
  444.                 str(mo:2,stmo2) ;
  445.                 str(dy:2,stdy2) ;
  446.                 stdt2 := concat (styr2,stmo2,stdy2)
  447.             end ;
  448.         if stdt1 > stdt2 then
  449.                 greater_date := 1
  450.         else if stdt2 > stdt1 then
  451.                 greater_date := 2
  452.         else { both equal }
  453.                 greater_date := 0
  454.     end ; { --- of greater_date --- }
  455.  
  456. { ------------------------------------------------------------ }
  457.  
  458. procedure greg_to_jul (dt : date ; var jdt : juldate) ;
  459. { converts a gregorian date to a julian date }
  460.   begin
  461.     jdt.yr := dt.yr ;
  462.     if (dt.yr = 0) and (dt.mo = 0) and (dt.dy = 0) then
  463.         jdt.day := 0
  464.     else
  465.       begin
  466.         if (leapyear(dt.yr)) and (dt.mo > 2) then
  467.             jdt.day := 1
  468.         else
  469.             jdt.day := 0 ;
  470.         jdt.day := jdt.day + monthtotal[dt.mo] + dt.dy
  471.       end
  472.   end ;  { --- procedure greg_to_jul --- }
  473.  
  474. { ------------------------------------------------------------ }
  475.  
  476. procedure jul_to_greg (jdt : juldate ; var dt : date) ;
  477. { converts a julian date to a gregorian date }
  478.   var
  479.       i, workday : integer ;
  480.   begin
  481.     dt.yr := jdt.yr ;
  482.     if (jdt.yr = 0) and (jdt.day = 0) then
  483.       begin
  484.         dt.mo := 0 ; dt.dy := 0
  485.       end
  486.     else
  487.       begin
  488.         workday := jdt.day ;
  489.         if (leapyear(jdt.yr)) and (workday > 59) then
  490.             workday := workday - 1 ;   { make it look like a non-leap year }
  491.         i := 1 ;
  492.         repeat
  493.             i := i + 1
  494.         until not (workday > monthtotal[i]) ;
  495.         i := i - 1 ;
  496.         dt.mo := i ;
  497.         dt.dy := workday - monthtotal[i] ;
  498.         if leapyear(jdt.yr) and (jdt.day = 60) then
  499.             dt.dy := dt.dy + 1
  500.       end
  501.   end ;  { --- procedure jul_to_greg --- }
  502.  
  503. { ------------------------------------------------------------ }
  504.  
  505. procedure next_day (var dt : date) ;
  506.   { Adds one day to the date }
  507.     var
  508.         jdt  : juldate ;
  509.         leap : boolean ;
  510.     begin
  511.         greg_to_jul (dt,jdt) ;
  512.         jdt.day := jdt.day + 1 ;
  513.         leap := leapyear (dt.yr) ;
  514.         if (leap and (jdt.day = 367))
  515.         or (not leap and (jdt.day = 366)) then
  516.           begin
  517.             jdt.yr := jdt.yr + 1 ;
  518.             jdt.day := 1
  519.           end ;
  520.         jul_to_greg (jdt,dt)
  521.     end ;  { --- procedure next_day --- }
  522.  
  523. { ------------------------------------------------------------ }
  524.  
  525. procedure prev_day (var dt : date) ;
  526.   { Subtracts one day from the date }
  527.     var
  528.         jdt : juldate ;
  529.     begin
  530.         greg_to_jul (dt,jdt) ;
  531.         jdt.day := jdt.day - 1 ;
  532.         if jdt.day < 1 then
  533.           begin
  534.             jdt.yr := jdt.yr - 1 ;
  535.             if leapyear (jdt.yr) then
  536.                 jdt.day := 366
  537.             else
  538.                 jdt.day := 365
  539.           end ;
  540.         jul_to_greg (jdt,dt)
  541.     end ;  { --- procedure prev_day --- }
  542.  
  543. { ------------------------------------------------------------ }
  544.  
  545. function date_diff (dt1, dt2 : date) : real ;
  546.   { computes the number of days between two dates }
  547.     var
  548.         jdt1, jdt2 : juldate ;
  549.         i, num_leap_yrs : integer ;
  550.     begin
  551.         greg_to_jul (dt1, jdt1) ;
  552.         greg_to_jul (dt2, jdt2) ;
  553.  
  554.         num_leap_yrs := 0 ;         { adjust for leap years }
  555.         if dt2.yr > dt1.yr then
  556.           begin
  557.             for i := dt1.yr to dt2.yr - 1 do
  558.                 if leapyear(i) then
  559.                     num_leap_yrs := num_leap_yrs + 1
  560.           end
  561.         else if dt1.yr > dt2.yr then
  562.           begin
  563.             for i := dt2.yr to dt1.yr - 1 do
  564.                 if leapyear(i) then
  565.                     num_leap_yrs := num_leap_yrs - 1
  566.           end ;
  567.  
  568.         date_diff := jdt2.day - jdt1.day + ((jdt2.yr - jdt1.yr) * 365.0) + num_leap_yrs
  569.     end ;
  570.  
  571. { ------------------------------------------------------------ }
  572.  
  573. function month_diff (dt1, dt2 : date ) : integer ;
  574.   { Computes number of months between two dates, rounded.
  575.     30.4167 = 356/12, average number of days in a month. }
  576.     begin
  577.         month_diff := round((date_diff(dt1, dt2) + 1) / 30.4167)
  578.     end ;
  579.  
  580. { ------------------------------------------------------------ }
  581.  
  582. function equal_date (dt1, dt2 : date) : boolean ;
  583.   { Tests whether two dates are equal }
  584.     begin
  585.         equal_date := (dt1.mo = dt2.mo) and (dt1.dy = dt2.dy)
  586.                       and (dt1.yr = dt2.yr)
  587.     end ;
  588.  
  589. { ------------------------------------------------------------ }
  590.  
  591. function zeller (dt : date) : integer ;
  592. { Compute the day of the week using Zeller's Congruence.
  593.   From ROS 3.4 source code }
  594.   var
  595.     century: integer ;
  596.   begin
  597.     with dt do
  598.       begin
  599.         if mo > 2
  600.           then mo := mo - 2
  601.           else
  602.             begin
  603.               mo := mo + 10 ;
  604.               yr := pred(yr)
  605.             end ;
  606.         century := yr div 100 ;
  607.         yr := yr mod 100 ;
  608.         zeller := (dy - 1 + ((13 * mo - 1) div 5) + (5 * yr div 4) +
  609.             century div 4 - 2 * century + 1) mod 7
  610.       end
  611.   end ;  { function zeller }
  612.  
  613. { ------------------------------------------------------------ }
  614.  
  615. function build_full_date_str (dt : date) : fulldatestring ;
  616. { Build printable string of current date -- from ROS 3.4 source code. }
  617.   const
  618.     day: array [0..6] of string[6] =
  619.       ('Sun','Mon','Tues','Wednes','Thurs','Fri','Satur') ;
  620.     month: array [1..12] of string[9] =
  621.       ('January','February','March','April','May','June','July','August','September','October','November','December') ;
  622.   var
  623.     i: integer ;
  624.     s: fulldatestring ;
  625.  
  626.   function intstr(n, w: integer): str_type ;
  627.   { Return a string value of width w for the input integer n }
  628.     var
  629.       st: str_type ;
  630.     begin
  631.       str(n:w, st) ;
  632.       st := purgech (st,' ') ;
  633.       intstr := st
  634.     end ;
  635.  
  636.   begin { build_full_date_str }
  637.     with dt do
  638.       begin
  639.         if  (mo = 0) and (dy = 0) and (yr = 0) then
  640.             s := 'No Date'
  641.         else
  642.             s := day[zeller(dt)] + 'day, ' +
  643.                  month[mo] + ' ' + intstr(dy, 2) + ', ' + intstr(yr, 4) ;
  644.         if length (s) < fdslen then
  645.             s := pad (s,' ',fdslen)
  646.       end ;
  647.     build_full_date_str := s
  648.   end ; { function build_full_date_str }
  649.  
  650. { ----------------------------------------------------------------- }
  651.  
  652. procedure getdate (var dt : date) ;
  653.   { get DOS system date }
  654.  
  655.     var regs : registers ;
  656.  
  657.     begin
  658.       with regs do
  659.         begin
  660.           AX := $2A00 ;
  661.           msdos(regs) ;
  662.           dt.yr := CX ;
  663.           dt.mo := DH ;
  664.           dt.dy := DL
  665.         end
  666.     end ; { proc getdate }
  667.  
  668. { ----------------------------------------------------------------- }
  669.  
  670. function date_and_time : str14 ;
  671.   { get DOS system date and time, return string }
  672.  
  673. var
  674.   year,
  675.   month,day,
  676.   hour,min  : string[2] ;
  677.   regs : registers ;
  678.  
  679. begin
  680.   with regs do
  681.     begin
  682.       AX := $2A00 ;
  683.       msdos(regs) ;
  684.       str(CX-1900,year) ;
  685.       str(DH,month) ;
  686.       str(DL,day) ;
  687.       AX := $2C00 ;
  688.       msdos (regs) ;
  689.       str(CH:2,hour) ;
  690.       str(CL:2,min) ;
  691.     end ;
  692.   if  min[1] = ' ' then  min[1] := '0' ;
  693.   if  (hour[1] = ' ')
  694.   and (hour[2] = '0') then
  695.       hour := '00' ;
  696.   date_and_time := concat (month,'/',day,'/',year,' ',hour,':',min) ;
  697. end ; { function getdate }
  698.  
  699. end. { implementation }
  700.  
  701. { ----- EOF DATE24.PAS ------------------------------------------ }
  702.